import base64
import hashlib
import os
import random
import re
import uuid

import requests
import threading
import time
import string
import json
from functools import wraps

from flask import request, session, Response, Blueprint, jsonify, make_response, render_template, g
from flask_mail import Message

# from app.service.imageFunction import gene_code
# from OperationPlatform.settings import BASE_DIR
# from app.service.sendMailFunction import eMailClass
from sqlalchemy import desc, asc

from app.utils.authority import exception_handling
from .models import *
from app import app, db
from exts import _isLogin, mail, scheduler
from app.utils.error import ResponseError
# from app.utils.apSheduler import APScheduler

from app.utils.time_util import *
from app.utils.apscheduler_util import *

Aps_api = Blueprint('aps_api', __name__, template_folder='templates')


@Aps_api.route('/list.do', methods=['post'])
# @exception_handling
@_isLogin
def aps_list_do():
    def getTrigger(trigger):
        reData = {
            'timezone': str(trigger.timezone)
        }
        for index, name in enumerate(trigger.FIELD_NAMES):
            reData[name] = str(trigger.fields[index])
        return reData

    res = scheduler.get_jobs()
    return jsonify(data=list(map(lambda x: {
        'id': x.id, 'name': x.name, 'func': x.func.__name__,
        'trigger': getTrigger(x.trigger),
        'executor': x.executor,
        'args': x.args,
        'kwargs': x.kwargs,
        'misfire_grace_time': x.misfire_grace_time,
        'coalesce': x.coalesce,
        'max_instances': x.max_instances,
        'next_run_time': x.next_run_time.strftime('%Y-%m-%d %H:%M:%S') if x.next_run_time else None
    }, res)))
    # return jsonify(data=list(map(lambda x: x.__getstate__(), res)))


@Aps_api.route('/create.do', methods=['post'])
@exception_handling
@_isLogin
def aps_add_job_do():
    '''
    创建任务
    :trigger: 定时任务:cron; 循环任务:interval
    :return:
    '''
    if str(g.user.role) != '1':
        raise ResponseError(2, '权限不足')
    _id = uuid.uuid1().hex
    name = request.values.get('name')
    name = name or _id
    func = request.values.get('func')
    misfire_grace_time = request.values.get('misfire_grace_time')
    misfire_grace_time = int(misfire_grace_time or 5)
    cabinet = json.loads(request.values.get('cabinet'))
    run_times = request.values.get('run_times')
    _kwargs = {'user': g.user.name, 'task_id': _id, 'task_name': name, 'run_times': run_times}
    job = QJobHistory(
        name=name,
        func_name=func,
        task_id=_id,
        run_times=run_times,
        time=int(time.time()),
        userid=g.user.username,
        status=0
    )
    if run_times == '0':
        # 循环
        sconDict = {
            1: 1, 2: 2, 3: 5, 4: 10, 5: 30,
            6: 1, 7: 2, 8: 5, 9: 12,
            10: 1
        }
        _time = int(request.values.get('time'))
        _kwargs['run_time'] = {'time': _time}
        job.run_time = json.dumps(_kwargs['run_time'])
        if _time <= 5:
            scheduler.add_job(id=_id, name=name, func=eval(func), trigger='cron',
                              args=(cabinet,), kwargs=_kwargs, misfire_grace_time=misfire_grace_time,
                              minute='*/{}'.format(sconDict[_time]))
        elif _time < 10:
            scheduler.add_job(id=_id, name=name, func=eval(func), trigger='cron',
                              args=(cabinet,), kwargs=_kwargs, misfire_grace_time=misfire_grace_time,
                              hour='*/{}'.format(sconDict[_time]))
        else:
            scheduler.add_job(id=_id, name=name, func=eval(func), trigger='cron',
                              args=(cabinet,), kwargs=_kwargs, misfire_grace_time=misfire_grace_time,
                              day='*/{}'.format(sconDict[_time]))
    # scheduler.add_job(id=_id, name=name, func=eval(func), trigger='cron',
    #                   args=(cabinet,), kwargs=_kwargs, misfire_grace_time=misfire_grace_time,
    #                   day='*/{}'.format(_time['day']) if _time['day'] else '*',
    #                   hour='*/{}'.format(_time['hour']) if _time['hour'] else '*',
    #                   minute='*/{}'.format(_time['minute']) if _time['minute'] else '*',
    #                   second='*/{}'.format(_time['second']) if _time['second'] else '0')

    elif run_times == '1':
        # 运行一次
        next_run_time = request.values.get('next_run_time')
        _kwargs['run_time'] = {'next_run_time': next_run_time}
        job.run_time = _kwargs['run_time']
        y, m, d, h, min, s = datetime2ymdhms(next_run_time)
        scheduler.add_job(id=_id, name=name or _id, func=eval(func), trigger='cron',
                          misfire_grace_time=misfire_grace_time, args=(cabinet,),
                          kwargs=_kwargs, year=y, month=m, day=d, hour=h, minute=min,
                          second=s)
    else:
        print('no run')
        # 不运行
        raise ResponseError(1, 'run times error')
    db.session.add(job)
    db.session.commit()
    return jsonify()


@Aps_api.route('/pause.do', methods=['get', 'post'])
@exception_handling
@_isLogin
def aps_pause_task_do():
    '''
    暂停任务
    :return:
    '''
    if str(g.user.role) != '1':
        raise ResponseError(2, '权限不足')
    _id = request.values.get('id')
    scheduler.pause_job(str(_id))
    job = QJobHistory.query.filter_by(task_id=_id).order_by(desc('time')).first()
    if job:
        newJob = QJobHistory(
            name=job.name,
            func_name=job.func_name,
            task_id=_id,
            run_times=job.run_times,
            run_time=job.run_time,
            time=int(time.time()),
            userid=g.user.username,
            status=1
        )
        db.session.add(newJob)
        db.session.commit()
    return jsonify()


@Aps_api.route('/resume.do', methods=['get', 'post'])
@exception_handling
@_isLogin
def aps_resume_task_do():
    '''
    恢复任务
    :return:
    '''
    if str(g.user.role) != '1':
        raise ResponseError(2, '权限不足')
    _id = request.values.get('id')
    scheduler.resume_job(str(_id))
    job = QJobHistory.query.filter_by(task_id=_id).order_by(desc('time')).first()
    if job:
        newJob = QJobHistory(
            name=job.name,
            task_id=_id,
            func_name=job.func_name,
            run_times=job.run_times,
            run_time=job.run_time,
            time=int(time.time()),
            userid=g.user.username,
            status=2
        )
        db.session.add(newJob)
        db.session.commit()
    return jsonify()


@Aps_api.route('/detail.do', methods=['post'])
@exception_handling
@_isLogin
def aps_get_task_detail_do():
    '''
    任务详情
    :return:
    '''
    _id = request.values.get('id')
    job = scheduler.get_job(_id)
    print(job)
    return jsonify()


@Aps_api.route('/remove.do', methods=['post'])
@exception_handling
@_isLogin
def aps_remove_task():
    '''
    移除任务
    :return:
    '''
    if str(g.user.role) != '1':
        raise ResponseError(2, '权限不足')
    _id = request.values.get('id')
    try:
        scheduler.remove_job(str(_id))
    except:
        pass
    job = QJobHistory.query.filter_by(task_id=_id).order_by(desc('time')).first()
    if job:
        newJob = QJobHistory(
            name=job.name,
            func_name=job.func_name,
            task_id=_id,
            run_times=job.run_times,
            run_time=job.run_time,
            time=int(time.time()),
            userid=g.user.username,
            status=-1
        )
        db.session.add(newJob)
        db.session.commit()
    return jsonify()
